home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / hppicmd / hppicmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-22  |  28.1 KB  |  964 lines

  1. /* 
  2.  * ultracmd.c --
  3.  *
  4.  *    Program for dealing with the Ultranet VME adapter board..
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/proto.c,v 1.3 90/01/12 12:03:36 douglis Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include "sprite.h"
  21. #include "option.h"
  22. #include <stdio.h>
  23. #include <sys/file.h>
  24. #include <fs.h>
  25. #include "net.h"
  26. #include "netUltra.h"
  27. #include "/sprite/src/lib/include/dev/ultra.h"
  28. #include "/sprite/src/lib/include/dev/hppi.h"
  29. #include <status.h>
  30. #include <fmt.h>
  31. #include <ctype.h>
  32. #include "hppicmd.h"
  33.  
  34. /*
  35.  * The ucode file is in Intel format, which we don't have a constant for
  36.  * at the moment so borrow the VAX format.
  37.  */
  38.  
  39. #define CODE29K_FORMAT    FMT_SPARC_FORMAT
  40.  
  41. /*
  42.  * Variables settable via the command line.
  43.  */
  44.  
  45. Boolean    download = FALSE;    /* Download ucode to the adapter. */
  46. char    *dir = "/sprite/lib/hppi/code";  /* Directory containing ucode. */
  47. char    *file = NULL;        /* Ucode file to download. */
  48. Boolean reset = FALSE;        /* Reset the adapter. */
  49. Boolean getInfo = FALSE;    /* Get the adapter info. */
  50. char    *dev = "/dev";        /* Directory containing the device. */
  51. Boolean diag = FALSE;        /* Run diagnostic tests. */
  52. Boolean extDiag = FALSE;    /* Run extended diagnostic tests. */
  53. Boolean    external = FALSE;    /* Use external loopback when running
  54.                  * extended diagnostic tests. */
  55. char    *debug = NULL;        /* Set debugging output. */
  56. Boolean init = FALSE;        /* Send init command to adapter. */
  57. Boolean start = FALSE;        /* Send start command to the adapter. */
  58. char    *address = NULL;    /* Set adapter's Ultranet address. */
  59. char    *dsnd = NULL;        /* Send a datagram to the given host. */
  60. Boolean    drcv = FALSE;        /* Receive a datagram */
  61. int    count = 1;        /* Number of times to send the datagram. */
  62. int    repeat = 1;        /* Number of times to repeat the send test.*/
  63. int    size = 0;        /* Size of the datagram to send. */
  64. char    *echo = NULL;        /* Host should echo datagrams back to
  65.                  * sender.  Use for receiver of dsnd option. */
  66. char    *trace = FALSE;        /* Set tracing of activity. */
  67. char    *source = FALSE;    /* Send a steady stream of datagrams to
  68.                  * the given host. */
  69. char    *sink = FALSE;        /* Toggle sink of incoming datagrams. */
  70. char    *stat = FALSE;        /* Manipulate collection of statistics. */
  71. int    map = -1;        /* Set mapping threshold. */
  72. char    *board = "DST";        /* SRC, DST, or IOP board? */
  73. int    readReg = -1;        /* register to read */
  74. int    writeReg = -1;        /* register to write */
  75. int    writeValue = 0;        /* value to write into the above register */
  76. int    tsap = 0;        /* TSAP value to set */
  77. int    bcopy = -1;
  78. int    sg = -1;        
  79. int    noisyLoader = FALSE;
  80. int    boardFlags = -1;
  81. Boolean hardReset = FALSE;
  82. Boolean setup = FALSE;
  83. int    boardType;
  84.  
  85. Option optionArray[] = {
  86.     {OPT_DOC, NULL, NULL, "Usage: ultracmd [options] [device]"},
  87.     {OPT_DOC, NULL, NULL, "Default device is \"hppi0\""},
  88.     {OPT_TRUE, "dl", (Address) &download,
  89.     "Download micro-code into the adapter"},
  90.     {OPT_TRUE, "noisy", (Address) &noisyLoader,
  91.      "Print lots of messages during download"},
  92.     {OPT_STRING, "dir", (Address) &dir,
  93.     "Directory containing the micro-code files"},
  94.     {OPT_STRING, "f", (Address) &file,
  95.     "Micro-code file to download (default is to automatically pick one)"},
  96.     {OPT_TRUE, "r", (Address) &reset,
  97.     "Reset the adapter"},
  98.     {OPT_TRUE, "R", (Address) &hardReset,
  99.     "Hard reset the adapter"},
  100.     {OPT_TRUE, "t", (Address) &getInfo,
  101.     "Get type information from the adapter"},
  102.     {OPT_TRUE, "d", (Address) &diag,
  103.     "Run diagnostic tests on adapter"},
  104.     {OPT_TRUE, "ed", (Address) &extDiag,
  105.     "Run extended diagnostic tests on adapter"},
  106.     {OPT_TRUE, "ext", (Address) &external,
  107.     "Use external loopback when running extended diagnostics"},
  108.     {OPT_STRING, "dev", (Address) &dev,
  109.     "Directory containing the device"},
  110.     {OPT_STRING, "dbg", (Address) &debug,
  111.     "Ultranet device debugging output (on/off)"},
  112.     {OPT_INT, "flags", (Address) &boardFlags,
  113.     "Flags to send to the boards."},
  114.     {OPT_TRUE, "i", (Address) &init,
  115.     "Send initialization command to adapter"},
  116.     {OPT_TRUE, "s", (Address) &start,
  117.     "Send start request to the adapter."},
  118.     {OPT_STRING, "a", (Address) &address,
  119.     "Set Ultranet address of adapter."},
  120.     {OPT_STRING, "dsnd", (Address) &dsnd,
  121.     "Send a datagram to the given address."},
  122.     {OPT_TRUE, "drcv", (Address) &drcv,
  123.      "Receive a datagram from any address."},
  124.     {OPT_INT, "cnt", (Address) &count,
  125.     "Number of times to send a datagram (use with -dsnd)."},
  126.     {OPT_INT, "repeat", (Address) &repeat,
  127.     "Number of times to repeat the send-datagram test (use with -dsnd)."},
  128.     {OPT_INT, "size", (Address) &size,
  129.     "Size of the datagram (use with -dsnd)."},
  130.     {OPT_STRING, "echo", (Address) &echo,
  131.     "Echo received datagrams back to sender (on/off)"},
  132.     {OPT_STRING, "trace", (Address) &trace,
  133.     "Start and stop tracing of ultra driver activity (on/off)"},
  134.     {OPT_STRING, "source", (Address) &source,
  135.     "Send a stream of datagrams to the given address."},
  136.     {OPT_STRING, "sink", (Address) &sink,
  137.     "Toggle sink of incoming datagrams (on/off)"},
  138.     {OPT_STRING, "stat", (Address) &stat,
  139.     "Manipulate collection of ultranet statistics (on/off/clear/get)"},
  140.     {OPT_INT, "m", (Address) &map,
  141.     "Set mapping threshold."},
  142.     {OPT_INT, "bcopy", (Address) &bcopy,
  143.     "Bcopy test data size."},
  144.     {OPT_INT, "sg", (Address) &sg,
  145.     "SG bcopy test data size."},
  146.     {OPT_TRUE, "setup", (Address)&setup,
  147.      "Set up the boards."},
  148.     {OPT_STRING, "board", (Address) &board,
  149.      "Board to use (src | dst | iop)."},
  150.     {OPT_INT, "rreg", (Address) &readReg,
  151.      "Read a board register."},
  152.     {OPT_INT, "wreg", (Address) &writeReg,
  153.      "Write a board register."},
  154.     {OPT_INT, "value", (Address) &writeValue,
  155.      "Value to write (use with -wreg)."},
  156.     {OPT_INT, "tsap", (Address) &tsap,
  157.      "TSAP value to use on datagrams"},
  158. };
  159. int numOptions = sizeof(optionArray) / sizeof(Option);
  160.  
  161. /*
  162.  * The following are the names of the diagnostic tests as listed in the
  163.  * uvm man page provided in the Ultranet documentation.
  164.  */
  165. static char    *diagNames[] = {
  166.     "EPROM checksum",
  167.     "Abbreviated RAM check",
  168.     "Interrupt controller and interval timer",
  169.     "Internal loopback",
  170.     "FIFO RAM check",
  171.     "Checksum gate arrays",
  172.     "NMI control logic"
  173. };
  174. /*
  175.  * The following are the names of the extended diagnostic tests as
  176.  * listed in the uvm man page.
  177.  */
  178. static char    *extDiagNames[] = {
  179.     "EPROM checksum",
  180.     "Full RAM check",
  181.     "Interrupt controller and interval timer",
  182.     "Internal or external loopback",
  183.     "FIFO RAM check",
  184.     "Checksum gate arrays",
  185.     "NMI control logic",
  186.     "DMA to hosts memory using VME bus",
  187.     "Extended FIFO RAM check",
  188.     "FIFO Control logic"
  189. };
  190.  
  191. char    *myname;
  192. void    Download();
  193.  
  194. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  195.  
  196. char    *device = "hppi0";
  197.  
  198.  
  199. /*
  200.  *----------------------------------------------------------------------
  201.  *
  202.  * main --
  203.  *
  204.  *    Parse the arguments and call the correct procedure.
  205.  *
  206.  * Results:
  207.  *    None.
  208.  *
  209.  * Side effects:
  210.  *    The state of the adapter board may be modified.
  211.  *
  212.  *----------------------------------------------------------------------
  213.  */
  214.  
  215. int
  216. main(argc, argv)
  217.     int        argc;
  218.     char    *argv[];
  219. {
  220.     int            argsLeft;
  221.     char        deviceName[FS_MAX_PATH_NAME_LENGTH];
  222.     int            fd;
  223.     ReturnStatus    status;
  224.  
  225.     myname = argv[0];
  226.     argsLeft = Opt_Parse(argc, argv, optionArray, numOptions, 0);
  227.     if (argsLeft > 2) {
  228.     Opt_PrintUsage(argv[0], optionArray, numOptions);
  229.     exit(1);
  230.     }
  231.     if (download + reset + getInfo + diag + extDiag + (debug != NULL) +
  232.     init + start + (address != NULL) + (dsnd != NULL) + drcv +
  233.     (echo != NULL) + (trace != NULL) + (source != NULL) +
  234.     (sink != NULL) + (stat != NULL) + (tsap != 0) +
  235.     (map >= 0) + hardReset + setup +
  236.     (readReg != -1) + (writeReg != -1) + (boardFlags != -1) > 1) {
  237.     printf("You can only specify one of the following options:\n");
  238.     printf("-dl, -r, -t, -d, -ed, -dbg, -i, -s, -a, -dsnd, -echo\n");
  239.     printf("-trace, -source, -stat, -m, -R, -rreg, -wreg, -flags\n");
  240.     Opt_PrintUsage(argv[0], optionArray, numOptions);
  241.     exit(1);
  242.     }
  243.     if ((external == TRUE) && (extDiag == FALSE)) {
  244.     printf("The -ext option can only be used with the -ed option\n");
  245.     Opt_PrintUsage(argv[0], optionArray, numOptions);
  246.     exit(1);
  247.     }
  248.  
  249.     if (!strcasecmp (board, "dst")) {
  250.     boardType = DEV_HPPI_DST_BOARD;
  251.     } else if (!strcasecmp (board, "src")) {
  252.     boardType = DEV_HPPI_SRC_BOARD;
  253.     } else if (!strcasecmp (board, "iop")) {
  254.     boardType = DEV_HPPI_IOP_BOARD;
  255.     } else {
  256.     printf ("-board must be \"dst\", \"src\" or \"iop\"\n");
  257.     Opt_PrintUsage (argv[0], optionArray, numOptions);
  258.     exit (1);
  259.     }
  260.     if (argsLeft == 2) {
  261.     device = argv[1];
  262.     }
  263.     sprintf(deviceName, "%s/%s", dev, device);
  264.     fd = open(deviceName, O_RDONLY);
  265.     if (fd < 0) {
  266.     printf("Can't open device \"%s\"\n", deviceName);
  267.     perror("");
  268.     Opt_PrintUsage(argv[0], optionArray, numOptions);
  269.     exit(1);
  270.     }
  271.     if (debug) {
  272.     int flag;
  273.     if (!strcasecmp(debug, "on")) {
  274.         flag = 1;
  275.     } else if (!strcasecmp(debug, "off")) {
  276.         flag = 0;
  277.     } else {
  278.         printf("Invalid parameter to -dbg. Must be \"on\" or \"off\"\n");
  279.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  280.         exit(1);
  281.     }
  282.     status = Fs_IOControl(fd, IOC_HPPI_DEBUG, sizeof(int), &flag, 0, 0);
  283.     if (status != SUCCESS) {
  284.         printf("Fs_IOControl returned 0x%x\n", status);
  285.     }
  286.     }
  287.     if (reset) {
  288.     status = Fs_IOControl(fd, IOC_HPPI_RESET, 0, NULL, 0, 0);
  289.     if (status != SUCCESS) {
  290.         printf("Fs_IOControl returned 0x%x\n", status);
  291.     }
  292.     }
  293.     if (hardReset) {
  294.     status = Fs_IOControl(fd, IOC_HPPI_HARD_RESET, 0, NULL, 0, 0);
  295.     if (status != SUCCESS) {
  296.         printf("Fs_IOControl returned 0x%x\n", status);
  297.     }
  298.     }
  299.  
  300.     if (setup) {
  301.     status = Fs_IOControl (fd, IOC_HPPI_SETUP, 0, NULL, 0, 0);
  302.     if (status != SUCCESS) {
  303.         printf ("setup: Fs_IOControl returned 0x%x\n", status);
  304.     }
  305.     }
  306.  
  307.     if (writeReg >= 0) {
  308.     Dev_HppiRegCmd regCmd;
  309.     regCmd.board = boardType;
  310.     regCmd.offset = writeReg;
  311.     regCmd.value = writeValue;
  312.     status = Fs_IOControl (fd, IOC_HPPI_WRITE_REG, sizeof (regCmd),
  313.                    ®Cmd, 0, NULL);
  314.     if (status != SUCCESS) {
  315.         printf ("Fs_IOControl returned 0x%x\n", status);
  316.     } else {
  317.         printf ("%s board register at 0x%x offset was written with 0x%x\n",
  318.             board, writeReg, writeValue);
  319.     }
  320.     }
  321.  
  322.     if (readReg >= 0) {
  323.     Dev_HppiRegCmd regCmd, regReply;
  324.     regCmd.board = boardType;
  325.     regCmd.offset = readReg;
  326.     regCmd.value = 0;
  327.     status = Fs_IOControl (fd, IOC_HPPI_READ_REG, sizeof (regCmd),
  328.                    ®Cmd, sizeof (regReply), ®Reply);
  329.     if (status != SUCCESS) {
  330.         printf ("Fs_IOControl returned 0x%x\n", status);
  331.     } else {
  332.         printf ("%s board register at offset 0x%x was read as 0x%x\n",
  333.             board, regReply.offset, regReply.value);
  334.     }
  335.     }
  336.  
  337.     if (boardFlags >= 0) {
  338.     status = Fs_IOControl (fd, IOC_HPPI_SET_BOARD_FLAGS,
  339.                    sizeof (boardFlags), &boardFlags, 0, NULL);
  340.     if (status != SUCCESS) {
  341.         printf ("Fs_IOControl returned 0x%x\n", status);
  342.     } else {
  343.         printf ("Board flags set to 0x%x\n", boardFlags);
  344.     }
  345.     }
  346. #if 0
  347.     if (getInfo) {
  348.     Dev_UltraAdapterInfo    info;
  349.     status = Fs_IOControl(fd, IOC_ULTRA_GET_ADAP_INFO, 0, NULL, 
  350.             sizeof(Dev_UltraAdapterInfo), &info);
  351.     if (status != SUCCESS) {
  352.         printf("Fs_IOControl returned 0x%x\n", status);
  353.     } else {
  354.         printf(
  355.     "Model 99-%04d-%04d, Revision %d, Options %d, Firmware %d, Serial %d\n",
  356.         info.hwModel, info.hwVersion, info.hwRevision, 
  357.         info.hwOption, info.version, info.hwSerial);
  358.     }
  359.     }
  360.     if (diag) {
  361.     Dev_UltraDiag        cmd;
  362.     status = Fs_IOControl(fd, IOC_ULTRA_DIAG, 0, NULL, 
  363.             sizeof(Dev_UltraDiag), &cmd);
  364.     if (status != SUCCESS) {
  365.         printf("Fs_IOControl returned 0x%x\n", status);
  366.     } else {
  367.         if (cmd.error == 0) {
  368.         printf("All diagnostic tests passed.\n");
  369.         } else {
  370.         int    tmp = cmd.error;
  371.         int    i;
  372.         printf("The following diagnostic tests failed:\n");
  373.         for (i = 0; i < sizeof(int); i++) {
  374.             if (tmp & 1) {
  375.             printf("%2d: %s\n", i+1, diagNames[i]);
  376.             }
  377.             tmp >>= 1;
  378.         }
  379.         }
  380.     }
  381.     }
  382.     if (extDiag) {
  383.     Dev_UltraExtendedDiag    cmd;
  384.     cmd.externalLoopback = external;
  385.     status = Fs_IOControl(fd, IOC_ULTRA_EXTENDED_DIAG, sizeof(cmd), 
  386.             (Address) &cmd, sizeof(cmd), (Address) &cmd);
  387.     if (status != SUCCESS) {
  388.         printf("Fs_IOControl returned 0x%x\n", status);
  389.     } else {
  390.         if (cmd.error == 0) {
  391.         printf("All extended diagnostic tests passed.\n");
  392.         } else {
  393.         int    tmp = cmd.error;
  394.         int    i;
  395.         printf("The following extended diagnostic tests failed:\n");
  396.         for (i = 0; i < sizeof(int); i++) {
  397.             if (tmp & 1) {
  398.             printf("%2d: %s\n", i+1, extDiagNames[i]);
  399.             }
  400.             tmp >>= 1;
  401.         }
  402.         }
  403.     }
  404.     }
  405. #endif
  406.     if (download) {
  407.     Download(fd, dir, file, boardType);
  408.     }
  409. #if 0
  410.     if (init) {
  411.     status = Fs_IOControl(fd, IOC_ULTRA_INIT, 0, NULL, 0, NULL);
  412.     if (status != SUCCESS) {
  413.         printf("Fs_IOControl returned 0x%x\n", status);
  414.     } 
  415.     }
  416. #endif
  417.     if (start) {
  418.     status = Fs_IOControl(fd, IOC_HPPI_START, 0, NULL, 0, NULL);
  419.     if (status != SUCCESS) {
  420.         printf("Fs_IOControl returned 0x%x\n", status);
  421.     } 
  422.     }
  423.     if (address) {
  424.     Net_UltraAddress    ultraAddress;
  425.     int            count;
  426.     int            group;
  427.     int            unit;
  428.     count = sscanf(address,"%d/%d", &group, &unit);
  429.     if (count != 2) {
  430.         printf("%s: argument to -a is of form <group>/<unit>\n", myname);
  431.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  432.         exit(1);
  433.     }
  434.     if (group < 1 || group > 1000) {
  435.         printf("%s: group must be 1-1000\n", myname);
  436.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  437.         exit(1);
  438.     }
  439.     if (unit < 32 || unit > 62) {
  440.         printf("%s: unit must be 32-62\n", myname);
  441.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  442.         exit(1);
  443.     }
  444.     Net_UltraAddressSet(&ultraAddress, group, unit);
  445.     status = Fs_IOControl(fd, IOC_HPPI_ADDRESS, sizeof(Net_UltraAddress),
  446.             &ultraAddress, 0, NULL);
  447.     if (status != SUCCESS) {
  448.         printf("Fs_IOControl returned 0x%x\n", status);
  449.     } 
  450.     }
  451.  
  452.     if (tsap != 0) {
  453.     printf ("Setting tsap to 0x%08x\n", tsap);
  454.     status = Fs_IOControl (fd, IOC_HPPI_SET_TSAP, sizeof (tsap),
  455.                    &tsap, 0, NULL);
  456.     if (status != SUCCESS) {
  457.         printf ("Fs_IOControl returned 0x%x\n", status);
  458.     }
  459.     }
  460.  
  461.     if (drcv) {
  462.     status = Fs_IOControl(fd, IOC_HPPI_RECV_DGRAM, 0, NULL, 0, NULL);
  463.     if (status != SUCCESS) {
  464.         printf ("Fs_IOControl returned 0x%x\n", status);
  465.     }
  466.     }
  467.  
  468.     if (dsnd) {
  469.     Dev_UltraSendDgram    dgram;
  470.     int            pid;
  471.     int            n;
  472.     int            group;
  473.     int            unit;
  474.     n = sscanf(dsnd,"%d/%d", &group, &unit);
  475.     if (n != 2) {
  476.         printf("%s: argument to -dsnd is of form <group>/<unit>\n", myname);
  477.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  478.         exit(1);
  479.     }
  480.     if (group < 1 || group > 1000) {
  481.         printf("%s: group must be 1-1000\n", myname);
  482.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  483.         exit(1);
  484.     }
  485.     if (unit < 32 || unit > 62) {
  486.         printf("%s: unit must be 32-62\n", myname);
  487.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  488.         exit(1);
  489.     }
  490.     Net_UltraAddressSet(&dgram.address.address.ultra, group, unit);
  491.     dgram.count = count;
  492.     dgram.size = size;
  493.     dgram.useBuffer = FALSE;
  494.     while (repeat > 0) {
  495.         repeat--;
  496.         status = Fs_IOControl(fd, IOC_HPPI_SEND_DGRAM, 
  497.             sizeof(dgram), &dgram, sizeof(dgram), &dgram);
  498.         if (status != SUCCESS) {
  499.         printf("Fs_IOControl returned 0x%x\n", status);
  500.         break;
  501.         }
  502.         Time_Divide(dgram.time, count, &dgram.time);
  503.         printf("%d\t%d.%06d\n", size, dgram.time.seconds, 
  504.         dgram.time.microseconds);
  505.     }
  506.     }
  507.     if (echo) {
  508.     Dev_UltraEcho        echoParam;
  509.     if (!strcasecmp(echo, "on")) {
  510.         echoParam.echo = TRUE;
  511.     } else if (!strcasecmp(echo, "off")) {
  512.         echoParam.echo = FALSE;
  513.     } else {
  514.         printf("Invalid parameter to -echo. Must be \"on\" or \"off\"\n");
  515.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  516.         exit(1);
  517.     }
  518.     status = Fs_IOControl(fd, IOC_HPPI_ECHO, sizeof(echoParam),
  519.         &echoParam, 0, NULL);
  520.     if (status != SUCCESS) {
  521.         printf("Fs_IOControl returned 0x%x\n", status);
  522.     }
  523.     }
  524.     if (trace) {
  525.     int flag;
  526.     if (!strcasecmp(trace, "on")) {
  527.         flag = 1;
  528.     } else if (!strcasecmp(trace, "off")) {
  529.         flag = 0;
  530.     } else {
  531.         printf("Invalid parameter to -trace. Must be \"on\" or \"off\"\n");
  532.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  533.         exit(1);
  534.     }
  535.     status = Fs_IOControl(fd, IOC_HPPI_TRACE, sizeof(int), &flag, 0, 0);
  536.     if (status != SUCCESS) {
  537.         printf("Fs_IOControl returned 0x%x\n", status);
  538.     }
  539.     }
  540.     if (source) {
  541.     Dev_UltraSendDgram    dgram;
  542.     int            pid;
  543.     int            n;
  544.     int            group;
  545.     int            unit;
  546.     n = sscanf(source,"%d/%d", &group, &unit);
  547.     if (n != 2) {
  548.         printf("%s: argument to -dsnd is of form <group>/<unit>\n", myname);
  549.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  550.         exit(1);
  551.     }
  552.     if (group < 1 || group > 1000) {
  553.         printf("%s: group must be 1-1000\n", myname);
  554.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  555.         exit(1);
  556.     }
  557.     if (unit < 32 || unit > 62) {
  558.         printf("%s: unit must be 32-62\n", myname);
  559.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  560.         exit(1);
  561.     }
  562.     Net_UltraAddressSet(&dgram.address.address.ultra, group, unit);
  563.     dgram.count = count;
  564.     dgram.size = size;
  565.     dgram.useBuffer = FALSE;
  566.     while (repeat > 0) {
  567.         repeat--;
  568.         status = Fs_IOControl(fd, IOC_HPPI_SOURCE, 
  569.             sizeof(dgram), &dgram, sizeof(dgram), &dgram);
  570.         if (status != SUCCESS) {
  571.         printf("Fs_IOControl returned 0x%x\n", status);
  572.         break;
  573.         }
  574.         printf("%d\t%d.%06d\n", size, dgram.time.seconds, 
  575.         dgram.time.microseconds);
  576.     }
  577.     }
  578.     if (sink) {
  579.     Dev_UltraSink        sinkParam;
  580.     int flag;
  581.     int packets;
  582.     if (!strcasecmp(sink, "on")) {
  583.         flag = 1;
  584.     } else if (!strcasecmp(sink, "off")) {
  585.         flag = 0;
  586.     } else {
  587.         printf("Invalid parameter to -sink. Must be \"on\" or \"off\"\n");
  588.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  589.         exit(1);
  590.     }
  591.     status = Fs_IOControl(fd, IOC_HPPI_SINK, sizeof(int), &flag, 
  592.             sizeof(sinkParam), &sinkParam);
  593.     if (status != SUCCESS) {
  594.         printf("Fs_IOControl returned 0x%x\n", status);
  595.     } else {
  596.         printf("%d packets sunk\n", sinkParam.packets);
  597.     }
  598.     }
  599.     if (stat) {
  600.     Dev_UltraStats        statParam;
  601.     int            ioctl;
  602.     int            flag;
  603.     int            i;
  604.     if (!strcasecmp(stat, "on")) {
  605.         flag = 1;
  606.         ioctl = IOC_HPPI_COLLECT_STATS;
  607.     } else if (!strcasecmp(stat, "off")) {
  608.         flag = 0;
  609.         ioctl = IOC_HPPI_COLLECT_STATS;
  610.     } else if (!strcasecmp(stat, "clear")) {
  611.         ioctl = IOC_HPPI_CLEAR_STATS;
  612.     } else if (!strcasecmp(stat, "get")) {
  613.         ioctl = IOC_HPPI_GET_STATS;
  614.     } else {
  615.         printf("Invalid parameter to -stat.\n");
  616.         printf("Must be \"on\",\"off\",\"clear\", or \"get\"\n");
  617.         Opt_PrintUsage(argv[0], optionArray, numOptions);
  618.         exit(1);
  619.     }
  620.     switch(ioctl) {
  621.         case IOC_HPPI_COLLECT_STATS:
  622.         status = Fs_IOControl(fd, ioctl, sizeof(int), &flag, 0,0);
  623.         break;
  624.         case IOC_HPPI_CLEAR_STATS:
  625.         status = Fs_IOControl(fd, ioctl, 0,0,0,0);
  626.         break;
  627.         case IOC_HPPI_GET_STATS:
  628.         status = Fs_IOControl(fd, ioctl, 0, 0, 
  629.                 sizeof(statParam), &statParam);
  630.         break;
  631.     }
  632.     if (status != SUCCESS) {
  633.         printf("Fs_IOControl returned 0x%x\n", status);
  634.     } else {
  635.         switch(ioctl) {
  636.         case IOC_HPPI_COLLECT_STATS:
  637.             break;
  638.         case IOC_HPPI_CLEAR_STATS:
  639.             break;
  640.         case IOC_HPPI_GET_STATS:
  641.             printf("Packets sent:\t%9d\n", statParam.packetsSent);
  642.             printf("Bytes sent  :\t%9d\n", statParam.bytesSent);
  643.             printf("Histogram of packets sent:\n");
  644.             for (i = 0; i < 33; i++) {
  645.             printf("[%2d,%2d):\t%9d\n", i, i+1, 
  646.                 statParam.sentHistogram[i]);
  647.             }
  648.             printf("Packets received:\t%9d\n", 
  649.                 statParam.packetsReceived);
  650.             printf("Bytes received  :\t%9d\n", 
  651.                 statParam.bytesReceived);
  652.             printf("Histogram of packets received:\n");
  653.             for (i = 0; i < 33; i++) {
  654.             printf("[%2d,%2d):\t%9d\n", i, i+1, 
  655.                 statParam.receivedHistogram[i]);
  656.             }
  657.             break;
  658.         }
  659.     }
  660.     }
  661.     if (map >= 0) {
  662.     status = Fs_IOControl(fd, IOC_HPPI_MAP_THRESHOLD, sizeof(int), &map, 
  663.             0, 0);
  664.     if (status != SUCCESS) {
  665.         printf("Fs_IOControl returned 0x%x\n", status);
  666.     } 
  667.     }
  668. #if 0
  669.     if (bcopy >= 0) {
  670.     Time    time;
  671.     status = Fs_IOControl(fd, IOC_ULTRA_BCOPY_TEST, sizeof(int), &bcopy, 
  672.             sizeof(Time), &time);
  673.     if (status != SUCCESS) {
  674.         printf("Fs_IOControl returned 0x%x\n", status);
  675.     } else {
  676.         printf("%d\t%d.%06d\n", bcopy, time.seconds, 
  677.         time.microseconds);
  678.     }
  679.     }
  680.     if (sg >= 0) {
  681.     Time    time;
  682.     status = Fs_IOControl(fd, IOC_ULTRA_SG_BCOPY_TEST, sizeof(int), &sg, 
  683.             sizeof(Time), &time);
  684.     if (status != SUCCESS) {
  685.         printf("Fs_IOControl returned 0x%x\n", status);
  686.     } else {
  687.         printf("%d\t%d.%06d\n", sg, time.seconds, 
  688.         time.microseconds);
  689.     }
  690.     }
  691. #endif
  692.     close(fd);
  693.     exit(0);
  694. }
  695.  
  696. /*
  697.  *----------------------------------------------------------------------
  698.  *
  699.  * Download --
  700.  *
  701.  *    Downloads the Ultranet adapter ucode onto the board..
  702.  *
  703.  * Results:
  704.  *    None.
  705.  *
  706.  * Side effects:
  707.  *    The ucode is loaded onto the board.
  708.  *
  709.  *----------------------------------------------------------------------
  710.  */
  711.  
  712. void
  713. Download(devFD, dir, file, boardType)
  714.     int        devFD;        /* Handle on the ultranet adapter. */
  715.     char    *dir;        /* Name of directory containing ucode files.*/
  716.     char    *file;        /* If non-NULL then name of the file to
  717.                  * download. */
  718.     int        boardType;    /* determines whether src or dst board is
  719.                  * being loaded */
  720. {
  721.     file29Hdr        fhdr;
  722.     optionalFile29Hdr    ofhdr;
  723.     section29Hdr    *sectionPtr, *curSectPtr;
  724.     int        fd;
  725.     char    path[FS_MAX_PATH_NAME_LENGTH];
  726.     int        bytesRead;
  727.     int totalWordsExpected = 0;
  728.     int sectionCtr;
  729.     int tmp;
  730.     struct {
  731.     Dev_HppiLoadHdr    hdr;
  732.     int buffer[MAX_PACKET_SIZE/sizeof(int)];
  733.     } loadCmd;
  734.     int            readBuffer[MAX_PACKET_SIZE/sizeof(int)];
  735.     Dev_HppiGo        goCmd;
  736.     ReturnStatus    status;
  737.     int            fmtStatus;
  738.     int            inSize;
  739.     int            outSize;
  740.     int            bytesSent = 0;
  741.     int            address;
  742.     int            readNow;
  743.     int            i;
  744.  
  745.     
  746.     if (file == NULL) {
  747.     if (boardType == DEV_HPPI_SRC_BOARD) {
  748.         sprintf(path, "%s/srcCode", dir);
  749.     } else {
  750.         sprintf(path, "%s/dstCode", dir);
  751.     }
  752.     } else {
  753.     sprintf(path,"%s/%s", dir, file);
  754.     }
  755.     fd = open(path, O_RDONLY);
  756.     if (fd < 0) {
  757.     printf("%s: could not open code file \"%s\"\n", myname, path);
  758.     perror(NULL);
  759.     exit (1);
  760.     }
  761.  
  762.     if (read (fd, readBuffer, sizeof (fhdr)) != sizeof (fhdr)) {
  763.     printf ("%s: could not read file header (%s)\n", myname, path);
  764.     perror (NULL);
  765.     exit (1);
  766.     }
  767.  
  768.     inSize = outSize = sizeof (fhdr);
  769.     fmtStatus = Fmt_Convert ("h2w3h2", CODE29K_FORMAT, &inSize, readBuffer,
  770.                  FMT_MY_FORMAT, &outSize, &fhdr);
  771.     if (fmtStatus != FMT_OK) {
  772.     printf ("%s: couldn't format convert file header\n", myname);
  773.     perror (NULL);
  774.     exit (1);
  775.     }
  776.  
  777.     if (noisyLoader) {
  778.     printf ("\nFILE HEADER information:\nid: %x\n", fhdr.id);
  779.     printf ("Total section headers: %d\n", fhdr.sectionHdrCtr);
  780.     printf ("File creation date: %s\n", ctime (&fhdr.timestamp));
  781.     printf ("Symbols starts at file offset: %x\n", fhdr.symbolFp);
  782.     printf ("Total symbols count: %ld\n", fhdr.symbolCtr);
  783.         printf ("Optional file header length: %d\n",
  784.             fhdr.optionalFhdrLength);
  785.         printf ("File header flags: 0x%x <octal: %o>\n",
  786.             fhdr.fhdrFlags, fhdr.fhdrFlags);
  787.     }
  788.  
  789.     if (fhdr.optionalFhdrLength != 0)
  790.     {
  791.     if (read (fd, readBuffer, sizeof (ofhdr)) != sizeof (ofhdr)) {
  792.         printf ("%s: could not load code\n", myname);
  793.         exit (1);
  794.     }
  795.  
  796.     inSize = outSize = sizeof (ofhdr);
  797.     fmtStatus = Fmt_Convert ("h2w6", CODE29K_FORMAT, &inSize, readBuffer,
  798.                  FMT_MY_FORMAT, &outSize, &ofhdr);
  799.     if (fmtStatus != FMT_OK) {
  800.         printf ("%s: couldn't format convert optional file header\n",
  801.             myname);
  802.         perror (NULL);
  803.         exit (1);
  804.     }
  805.  
  806.     if (noisyLoader) {
  807.         printf ("OPTIONAL FILE HEADER information:\nID: %x, version: %x\n",
  808.             ofhdr.id, ofhdr.version);
  809.         printf ("Size of executible codes: %lx\n", ofhdr.executibleSize);
  810.         printf ("Size of constant data: %lx\n", ofhdr.dataSize);
  811.         printf ("Size of uninitialized data: %lx\n", ofhdr.bssSize);
  812.         printf ("Executible code entry: %lx\n", ofhdr.entryAddr);
  813.         printf ("Base of .text section: %lx\n", ofhdr.codeBaseAddr);
  814.         printf ("Base of constant data: %lx\n", ofhdr.dataBaseAddr);
  815.     }
  816.     totalWordsExpected = (ofhdr.executibleSize + ofhdr.dataSize) / 4;
  817.     }
  818.     sectionCtr = fhdr.sectionHdrCtr;
  819.  
  820. /*
  821.       Read in all the section headers from the file and store them
  822.       in memory. After the section headers comes the loadable data. But
  823.       the load addresses are embedded in the section headers. Therefore,
  824.       the headers have to be extracted before the loadable data can be
  825.       read.
  826. */
  827.  
  828.     if (sectionCtr > 0)
  829.     {
  830.     tmp = sectionCtr * sizeof (section29Hdr);
  831.     if ((sectionPtr = (section29Hdr *)malloc (tmp)) == NULL) {
  832.         printf ("%s: can't allocate section headers\n", myname);
  833.         perror (NULL);
  834.         exit (1);
  835.     }
  836.     if (read (fd, readBuffer, tmp) != tmp) {
  837.         printf ("%s: can't read %d section headers\n", myname, sectionCtr);
  838.         perror (NULL);
  839.         exit (1);
  840.     }
  841.  
  842.     inSize = outSize = tmp;
  843.     fmtStatus = Fmt_Convert ("{b8w6h2w}*", CODE29K_FORMAT, &inSize,
  844.                  readBuffer, FMT_MY_FORMAT, &outSize,
  845.                  sectionPtr);
  846.     if (fmtStatus != FMT_OK) {
  847.         printf ("%s: couldn't format convert section header\n", myname);
  848.         perror (NULL);
  849.         exit (1);
  850.     }
  851.  
  852.     }
  853.  
  854.     curSectPtr = sectionPtr;
  855.     while (sectionCtr-- > 0) {
  856.     address = curSectPtr->loadAddr;
  857.  
  858.     if (!(((curSectPtr->sectionFlag) == STYPE_REG) ||
  859.           (((curSectPtr->sectionFlag) & STYPE_TEXT) == STYPE_TEXT)    ||
  860.           (((curSectPtr->sectionFlag) & STYPE_DATA) == STYPE_DATA)    ||
  861.           (((curSectPtr->sectionFlag) & STYPE_LIT) == STYPE_LIT))) {
  862.         continue;
  863.     }
  864.  
  865.     if (noisyLoader) {
  866.         printf ("SECTION HEADER <%s> information:\n",
  867.             curSectPtr->sectionName);
  868.         printf ("Load to address: %lx, size: %ld bytes\n",
  869.             curSectPtr->loadAddr, curSectPtr->sectionSize);
  870.         printf ("Virtual address: %lx\n", curSectPtr->virtualAddr);
  871.         printf ("Raw data starts at offset: %lx\n", curSectPtr->rawdFp);
  872.         printf ("Relocation info starts at offset: %lx\n",
  873.             curSectPtr->relocFp);
  874.         printf ("Line number info starts at offset: %lx\n",
  875.             curSectPtr->lineFp);
  876.         printf ("Total relocation entries: %d\n", curSectPtr->relocCtr);
  877.         printf ("Total line number entries: %d\n", curSectPtr->lineCtr);
  878.         printf ("Section flag = 0x%x (%o)\n",
  879.             curSectPtr->sectionFlag, curSectPtr->sectionFlag);
  880.     }
  881.  
  882. /*
  883.  *    Read and load one section.  First, insure that the current
  884.  *    file pointer is the same as curSectPtr->rawdFp.
  885.  */
  886.     tmp = lseek (fd, (long)0, L_INCR);
  887.     if (tmp != curSectPtr->rawdFp) {
  888.         if (noisyLoader) {
  889.         printf ("Current fp = %x, section raw data fp = %x\n",
  890.             tmp, curSectPtr->rawdFp);
  891.         }
  892.         lseek (fd, curSectPtr->rawdFp, L_SET);
  893.     }
  894.  
  895.     while (curSectPtr->sectionSize > 0) {
  896.         if (curSectPtr->sectionSize > MAX_PACKET_SIZE) {
  897.         readNow = MAX_PACKET_SIZE;
  898.         } else {
  899.         readNow = curSectPtr->sectionSize;
  900.         }
  901.         loadCmd.hdr.board = boardType;
  902.         loadCmd.hdr.size = readNow;
  903.         loadCmd.hdr.startAddress = address;
  904.         if (read (fd, (Address)readBuffer, readNow) != readNow) {
  905.         printf ("%s: read error section %d with %d bytes left.\n",
  906.             myname, sectionCtr, curSectPtr->sectionSize);
  907.         perror (NULL);
  908.         exit (1);
  909.         }
  910.  
  911.         inSize = outSize = readNow;
  912.  
  913.         fmtStatus = Fmt_Convert ("w*", CODE29K_FORMAT, &inSize, readBuffer,
  914.                      FMT_MY_FORMAT, &outSize, loadCmd.buffer);
  915.  
  916.         status = Fs_IOControl (devFD, IOC_HPPI_LOAD, sizeof (loadCmd),
  917.                    (Address)&loadCmd, 0, NULL);
  918.         if (status != SUCCESS) {
  919.         printf ("%s: Fs_IOControl returned 0x%x\n", myname, status);
  920. #if 0
  921.         perror (NULL);
  922.         exit (1);
  923. #endif
  924.         }
  925.         curSectPtr->sectionSize -= readNow;
  926.         bytesSent += readNow;
  927.         address += readNow;
  928.         if (noisyLoader) {
  929.         putchar ('.');
  930.         fflush (stdout);
  931.         }
  932.     }
  933.     curSectPtr++;
  934.     }
  935.  
  936.     if (sectionPtr != NULL) {
  937.     free (sectionPtr);
  938.     }
  939.  
  940. #ifdef    NOT_NOW
  941.     if (bytesSent != totalWordsExpected) {
  942.     printf ("Expected to load %d words, but sent %d\n", totalWordsExpected,
  943.         bytesSent);
  944.     }
  945. #endif
  946.  
  947.     printf ("%s: loaded %d (0x%x) words\n", myname, (bytesSent / 4),
  948.         (bytesSent / 4));
  949.  
  950.     /*
  951.      * Now send the start address.
  952.      */
  953.     goCmd.startAddress = ofhdr.entryAddr;
  954.     goCmd.board = boardType;
  955.     status = Fs_IOControl(devFD, IOC_HPPI_GO, sizeof(goCmd), 
  956.         (Address) &goCmd, 0, NULL);
  957.     if (status != SUCCESS) {
  958.     printf("Fs_IOControl returned 0x%x\n", status);
  959.     exit(1);
  960.     }
  961. }
  962.  
  963.  
  964.